﻿using Microsoft.VisualStudio.TestPlatform.UnitTestFramework;
using Padsurface.Audio.Engine;
using Padsurface.Tests;
using System;

namespace Padsurface.Audio.Tests.Unit.BeatsPerMinuteCalculatorSpecifications
{
    public abstract class WhenGetBeat : TestBase
    {
        protected abstract TimeSpan CurrenTime { get; }
        protected abstract double BeatsPerMinute { get; }
        protected double Result { get; private set; }

        protected override void Act()
        {
            Result = BeatsPerMinuteCalculator.GetBeat(CurrenTime, BeatsPerMinute);
        }
    }

    [TestClass]
    public class WhenGetBeatGivenCurrenTimeIsZeroAndBpmIsZero : WhenGetBeat
    {
        protected override TimeSpan CurrenTime { get { return TimeSpan.Zero; } }
        protected override double BeatsPerMinute { get { return 0; } }

        [TestMethod]
        public void ThenResultShouldBeZero()
        {
            Assert.AreEqual(0, Result);
        }
    }

    [TestClass]
    public class WhenGetBeatGivenCurrenTimeIsZeroAndBpmIsSixty : WhenGetBeat
    {
        protected override TimeSpan CurrenTime { get { return TimeSpan.Zero; } }
        protected override double BeatsPerMinute { get { return 60; } }

        [TestMethod]
        public void ThenResultShouldBeZero()
        {
            Assert.AreEqual(0, Result);
        }
    }

    [TestClass]
    public class WhenGetBeatGivenCurrenTimeIsOneSecondAndBpmIsSixty : WhenGetBeat
    {
        protected override TimeSpan CurrenTime { get { return TimeSpan.FromSeconds(1); } }
        protected override double BeatsPerMinute { get { return 60; } }

        [TestMethod]
        public void ThenResultShouldBeOne()
        {
            Assert.AreEqual(1, Result);
        }
    }

    [TestClass]
    public class WhenGetBeatGivenCurrenTimeIsOneSecondAndBpmIs120 : WhenGetBeat
    {
        protected override TimeSpan CurrenTime { get { return TimeSpan.FromSeconds(1); } }
        protected override double BeatsPerMinute { get { return 120; } }

        [TestMethod]
        public void ThenResultShouldBeTwo()
        {
            Assert.AreEqual(2, Result);
        }
    }

    [TestClass]
    public class WhenGetBeatGivenCurrenTimeIsOneSecondAndBpmIs30 : WhenGetBeat
    {
        protected override TimeSpan CurrenTime { get { return TimeSpan.FromSeconds(1); } }
        protected override double BeatsPerMinute { get { return 30; } }

        [TestMethod]
        public void ThenResultShouldBeA_Half()
        {
            Assert.AreEqual(0.5, Result);
        }
    }

    [TestClass]
    public class WhenGetBeatGivenCurrenTimeIsOneMinuteAndBpmIs120 : WhenGetBeat
    {
        protected override TimeSpan CurrenTime { get { return TimeSpan.FromMinutes(1); } }
        protected override double BeatsPerMinute { get { return 120; } }

        [TestMethod]
        public void ThenResultShouldBe120()
        {
            Assert.AreEqual(120, Result);
        }
    }
}
